使用python实现二叉树的深度优先遍历 |
您所在的位置:网站首页 › python 二叉树深度 › 使用python实现二叉树的深度优先遍历 |
本文将使用两种方式 -- 递归方法(易)与色彩标记(较难) 带大家实现二叉树的深度优先遍历,原理较为复杂但实现简单。数据结构小白也可以轻松上手实现,接下来请看正文。 首先,关于二叉树的深度优先遍历,我们必须知道的是:二叉树的深度优先遍历算法按照遍历顺序分为三种,分别是 1,先序遍历:根节点→左子树→右子树; 2,中序遍历:左子树→根节点→右子树; 3,后序遍历:左子树→右子树→根节点 而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。因此整个二叉深度遍历过程天然具有递归的性质。 举个例子:请看以下二叉树: 根据上述结构,使用python实现这棵二叉树的代码如下: # 构建二叉树的子结构 -- 节点 class BioTree: def __init__(self,val=0,left_node=None,right_node=None): self.val = val # 节点值 self.left_node = left_node # 左节点 self.right_node = right_node # 右节点 A,B,C,D,E,F,G,H,I = [BioTree(i) for i in "ABCDEFGHI"] # 构建二叉树 A.left_node = B A.right_node = C B.right_node = D C.left_node = E C.right_node = F E.left_node = G F.left_node = H F.right_node = I根据二叉树深度优先遍历的基础知识,我们可以分别写出他的: 先序遍历:A B D C E G F H I 中序遍历:B D A G E C H F I 后序遍历:D B G E H I F C A 根据二叉树天生具有的递归性质,我们首先使用较为简单易理解的递归方式实现二叉树的遍历,这里以先序遍历为例,代码如下: def preOrder(root): # 递归结束条件:只要当前节点为空,直接return if root is None: return # print()函数的位置决定了是先序、中序还是后序,只要调整这个就可以达到先序、中序、后序遍历的效果 print(root.val) preOrder(root.left_node) preOrder(root.right_node)这里对于每个节点只是做了简单的访问操作--print当前节点的值,如有其他需要只需要将print函数换成其他函数即可,对于先序、中序、后序三种遍历方式,只需要改变print函数的位置即可实现,比如当前是先序遍历,因为print函数先对结点进行访问,之后才对其左节点和右节点进行访问,如需实现中序遍历,只需要先访问其左节点,然后访问中间节点2,最后访问右节点即可,此时只需要将print函数位置调换到 preOrder(root.left_node) 和 preOrder(root.right_node) 中间即可,后序遍历原理类似。 以上是使用递归的形式对二叉树进行访问,实现较为简单,接下来将使用色彩标记法实现遍历二叉树。 准备工作:定义两种颜色作为已访问和未访问的代表,这里假设使用 white = 0 和 black = 1分别表示未访问节点和已访问节点,借鉴宽度优先的思想,为了便于实现访问,这里采用另一个数据结构 栈 作为存储容器,存储时将 (color, node) 有序对作为元素入栈,代码实现如下: def color_stack_order(root): white,black = 0,1 # 作为颜色标记,未访问的标记为白色,访问标记为黑色 stack = [(white,root)] # 将根节点以及初始的颜色作为有序对入栈 res = [] """ 这里默认为先序遍历,若需要改变访问的顺序只需要调整未访问节点和已访问节点的入栈顺序即可 """ while stack: # 站非空,表示还有节点未访问 color,node = stack.pop() # 以列表尾部作为栈顶 if node is None: # 排除某个节点左右节点为空时传入空节点导致报错 continue if color == white: # 未访问 stack.append((white,node.right_node)) # 当前节点的左右节点并未访问,将以有序对的形式入栈 stack.append((white,node.left_node)) stack.append((black,node)) # 标记当前节点已被访问,入栈 else: res.append(node.val) # 将已访问的节点的值顺序加入到一个列表中,作为访问得到的结果,也可以换成print函数得到和递归法一样的结果 return res对于上述代码,如果可以在初始化结点的时候使结点本身带有color这个属性:self.color = color,那么在做色彩标注法遍历时将不需要存储有序对,使用本身自带的属性进行判断即可。需要注意的是,根据栈的性质:后进先出,在进行结点访问时需要注意结点入栈的顺序,这里是和递归法刚好相反的,如本段代码中实现的先序遍历,就将根结点最后入栈,因此访问时也将最先访问这个根节点,之后才会访问其左右节点,以此实现先序遍历。 最后是两种方法的运行结果示例,编译工具,jupyter lab 以上就是本文的全部内容,如有遗漏欢迎补充,如有错误,欢迎斧正。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |